#ifndef CHARACTERFEATURE_H
#define CHARACTERFEATURE_H

#include "dtwenty_global.h"
#include "dtwentyitem.h"
#include "dtwentyitemcontainer.h"


#include <QTimer>
#include <QMetaEnum>


class DTWENTYSHARED_EXPORT CharacterFeature : public DTwentyItem
{
    Q_OBJECT

    class Data : public QSharedData
    {
    public:
        Data()
        {
            value = -1;
            id = -1;
        }

        Data(const Data& other) : QSharedData(other)
        {
            value = other.value;
            id = other.id;
        }

        int value;
        int id;
    };

    Q_PROPERTY(int value READ value WRITE setValue)
    Q_PROPERTY(int id READ id WRITE setId)


    QSharedDataPointer<Data> d;

public:
    enum HitDie
    {
        D4 = 4,
        D6 = 6,
        D8 = 8,
        D10 = 10,
        D12 = 12
    };

    enum SkillPoints
    {
        Untrained = 2,
        Educated = 4,
        Expert = 6,
        Master = 8
    };

    enum BaseBonus
    {
        Poor = 0,
        Ordinary = 1,
        Excellent = 2
    };

    enum SaveBonus
    {
        Normal = 0,
        Good = 1
    };

    Q_ENUMS(HitDie SkillPoints BaseBonus SaveBonus)


    Q_INVOKABLE CharacterFeature(QObject *parent = 0);
    CharacterFeature(const CharacterFeature& other);
    
    virtual int type() const
    {
        return qMetaTypeId<CharacterFeature*>();
    }

    int value() const
    {
        return d->value;
    }

    int id() const
    {
        return d->id;
    }

public slots:

    void setValue(int value)
    {
        d->value = value;
    }

    void setId(int id)
    {
        d->id = id;
    }
};
Q_DECLARE_METATYPE(CharacterFeature)


class DTWENTYSHARED_EXPORT CharacterFeatures : public DTwentyItemContainer
{
    Q_OBJECT

public:

    enum Feature
    {
        HitDie = 0,
        SkillPoints,
        BaseAttack,
        FortSave,
        RefSave,
        WillSave,

        Feature_CUSTOM
    };

    Q_ENUMS(Feature)


    Q_INVOKABLE CharacterFeatures(QObject* parent = 0) :
        DTwentyItemContainer(parent)
    {
        registerChildType<CharacterFeature>();

        QTimer::singleShot(0, this, SLOT(onInitChildren()));
    }

    CharacterFeatures(const CharacterFeatures& other) :
        DTwentyItemContainer(other)
    {
    }

    virtual int type() const
    {
        return qMetaTypeId<CharacterFeatures*>();
    }

protected slots:

    virtual void onInitChildren()
    {
        const QMetaObject* mo = metaObject();
        QMetaEnum me = mo->enumerator(mo->enumeratorOffset());


        // generate hit die, skill points, b.a, and saves if not exist
        QList<CharacterFeature*> features = findChildren<CharacterFeature*>(QString(), Qt::FindDirectChildrenOnly);
        for (int id = 0; id < Feature_CUSTOM; id++)
        {
            bool exists = false;
            foreach (const CharacterFeature* feature, features)
            {
                if (id == feature->id())
                {
                    exists = true;
                    break;
                }
            }

            if (exists)
            {
                continue;
            }

            CharacterFeature* feature = new CharacterFeature(this);
            feature->setName(me.valueToKey(id));
            feature->setId(id);

            const QMetaObject* fmo = feature->metaObject();
            int enumCount = fmo->enumeratorCount();
            int enumPos = id+fmo->enumeratorOffset();
            if (enumPos >= enumCount)
            {
                enumPos = enumCount-1;
            }

            QMetaEnum fme = fmo->enumerator(enumPos);
            feature->setValue(fme.value(0));
        }
    }
};

Q_DECLARE_METATYPE(CharacterFeatures)


#endif // CHARACTERFEATURE_H

